"Note: the grid is changed to reflect the scale such that it's one tenth the model's extent. If this is not acceptable it can be modified or eliminated here."
"First, the view is reset and then it refreshes itself. The reason for this is that if the view was already positioned at 0@0 and was rescaled, the view would not be automatically refreshed."
USA := SortedCollection sortBlock: [:a :b | a name < b name].
[fs nextLine = 'STATE'] whileTrue: [| st |
USA add: (st := State fromFile: fs).
Transcript show: 'just read ', st name; cr].
fs close.
USABounds := 0@0 corner: (USA inject: USA first boundingBox
into: [:bb : st | bb merge: st boundingBox]) corner!
writeStates
"State writeStates"
| fs |
fs := 'usa.data' asFilename writeStream.
USA do: [:st | st toFile: fs].
fs close! !
!State class methodsFor: 'accessing'!
usa
^USA isNil
ifTrue: [self error: 'USA has not been loaded!!!! See
State class method readStates']
ifFalse: [USA]!
usaBounds
^USABounds! !
Model subclass: #StateBrowser
instanceVariableNames: 'states currentState '
classVariableNames: ''
poolDictionaries: ''
category: 'USA'!
StateBrowser comment:
'The browser presents two views, an alphabetical list of the state names and a graphical map of the 50 United States. The user can select an individual state by clicking on its name in the list or by clicking directly within its border on the map. In either case, the two views are automatically updated such that the selected state is highlighted in both the list and the map.
The map display may be scrolled in both vertical and horizontal directions and can also be scaled via a menu selection.
___Technicals___
This application was originally written in Objectworks Release 4.0 and has been modified to run under Release 4.1.
This is a simple graphics application that displays a scrolling map of the 50 United States along with a scrolling list of their names. The user can click directly on a state to highlight it or can choose from the list of names. It is obviously very simple but with a little imagination it can be turned into something more sophisticated.
It requires an ASCII data file usa.data to be read in. This file defines the boundaries of the 50 states as polygons. See the State class method called readStates to make sure the filename is correct. After filing in the usa.st file, you should initialize the class variables in the State class (readStates) and then you can open a browser (StateBrowser | open).
I got the outlines for the states from a public domain MacDraw file. When printing a MacDraw file you can choose to print it to a file. This saves it as a PostScript file. I then edited the file to extract the polygons and manually entered each name. I then read the file in Smalltalk to create Smalltalk objects (flipping the x and y coordinates). To make a long story short, the polygons are now available as Smalltalk objects.
Enjoy.
Dan Benson
Siemens Corporate Research
755 College Road East
Princeton, NJ 08540
benson@siemens.siemens.com
'!
!StateBrowser methodsFor: 'colors'!
selectedStateBorderColor
^ColorValue black!
selectedStateInsideColor
^ColorValue red!
stateBorderColor
^ColorValue black!
stateInsideColor
^ColorValue white! !
!StateBrowser methodsFor: 'open'!
initialize
states := State usa copy asSortedCollection: [:a :b | a name < b name].
states do: [:s | s insideColor: self stateInsideColor; borderColor: self stateBorderColor].
currentState := nil.!
nameListView
| topView oneLine |
oneLine := TextAttributes default lineGrid + 3.
topView := DependentComposite new.
topView
add: (' States' withCRs asText allBold
asComposedText)
in: (LayoutFrame new
leftFraction: 0 offset: 5;
rightFraction: 1 offset: 0;
topFraction: 0 offset: 5;
bottomFraction: 0 offset: oneLine);
add: (LookPreferences edgeDecorator on:
(SelectionInListView on: self printItems: false
oneItem: false
aspect: #newStateList change:
#selectStateWithName: list: #allStateNames
menu: nil initialSelection:
#currentStateName))
in: (LayoutFrame new
leftFraction: 0 offset: 0;
rightFraction: 1 offset: 0;
topFraction: 0 offset: oneLine;
bottomFraction: 1 offset: 0).
^topView!
open
"StateBrowser new open"
self openWithListOnLeft: true!
openWithListOnLeft: aBoolean
"Open a ScheduledWindow on the receiver composed of two views, an alphabetical list of state names and a graphical map of the 50 United States. If aBoolean is true, put the name list view on the left, otherwise put it on the right."
"StateBrowser new openWithListOnLeft: false"
| window composite listWidth |
listWidth := 100.
window := ScheduledWindow new label: 'USA Browser'.
ifFalse: [self currentState: (self states detect: [:s
| s name = aString])]! !
!StateBrowser methodsFor: 'accessing'!
aboutText
^ValueHolder with:
'The browser presents two views, an alphabetical list of the state names and a graphical map of the 50 United States. The user can select an individual state by clicking on its name in the list or by clicking directly within its border on the map. In either case, the two views are automatically updated such that the selected state is highlighted in both the list and the map.
The map display may be scrolled in both vertical and horizontal directions and can also be scaled via a menu selection.
This application is a simple graphics example in Smalltalk that was originally written in Objectworks Release 4.0 and has been modified to run under Release 4.1. It was written by: